package ac.zlf.springmybatis.core.util;


import java.io.PrintStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;

public class DateHelper {
    public static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
    public static final String DEFAULT_TIME_PATTERN = "HH:mm";
    public static final String DIFF_YEARS = "diffYears";
    public static final String DIFF_MONTHS = "diffMonths";
    public static final String DIFF_DAYS = "diffDays";
    public static final String DIFF_HOURS = "diffHours";
    public static final String DIFF_MINUTES = "diffMinutes";

    public static Date getCurrentDate() {
        return new Date(System.currentTimeMillis());
    }

    public static Long getTime(Date date) {
        return date == null ? null : Long.valueOf(date.getTime());
    }

    public static Date getDate(Long time) {
        return time == null ? null : new Date(time.longValue());
    }

    public static String getMMDD(Date date) {
        return formatDate(date, "MM-dd");
    }

    public static String getMMDDHHMM(Date date) {
        return formatDate(date, "MM-dd HH:mm");
    }

    public static String getYYYYMMDD(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    public static String getYYYYMMDDHHMM(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm");
    }

    public static String getHHMM(Date date) {
        return formatDate(date, "HH:mm");
    }

    public static String formatDate(Date date, String format) {
        try {
            DateFormat simpleDateFormat = new SimpleDateFormat(format);
            return simpleDateFormat.format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateTime(String YYYYMMDDHHMM) {
        return parse2DateTime(YYYYMMDDHHMM, "yyyy-MM-dd HH:mm");
    }

    public static Date toDate(String YYYYMMDD) {
        return parse2DateTime(YYYYMMDD, "yyyy-MM-dd");
    }

    public static Date toTime(String HHMM) {
        return parse2DateTime(HHMM, "HH:mm");
    }

    public static Date parse2DateTime(String dateStr, String format) {
        try {
            DateFormat simpleDateFormat = new SimpleDateFormat(format);
            return simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int getWorkingDayCntByMonth(int year, int month) {
        int count = 0;
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, 1);
        while ((cal.get(1) == year) && (cal.get(2) < month)) {
            int day = cal.get(7);
            if ((day != 1) && (day != 7)) {
                count++;
            }
            cal.add(5, 1);
        }
        return count;
    }

    public static Calendar getMonday(Calendar givenDate) {
        Calendar cal = (Calendar) givenDate.clone();
        cal.set(7, 2);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 1);
        return cal;
    }

    public static Calendar getFriday(Calendar givenDate) {
        Calendar cal = (Calendar) givenDate.clone();
        cal.set(7, 6);
        cal.set(11, 23);
        cal.set(12, 59);
        cal.set(13, 59);

        return cal;
    }

    public static Calendar getNextMonday(Calendar givenDate, int offsetWeekCount) {
        Calendar cal = getMonday(givenDate);
        cal.add(5, offsetWeekCount * 7);
        return cal;
    }

    public static Calendar getNextFriday(Calendar givenDate, int offsetWeekCount) {
        Calendar cal = getFriday(givenDate);
        cal.add(5, offsetWeekCount * 7);

        return cal;
    }

    public static int getWeekNumber(Date givenDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(givenDate);
        return cal.get(7);
    }

    public static Date getOffsetDate(Date givenDate, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(givenDate);
        cal.add(5, offset);
        return new Date(cal.getTimeInMillis());
    }

    public static Date getOffsetDateForMonth(Date givenDate, int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(givenDate);
        calendar.add(2, offset);
        return new Date(calendar.getTimeInMillis());
    }

    public static boolean isAfterToday(Date date) {
        if (date == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        Calendar now = Calendar.getInstance();
        if ((cal.get(1) > now.get(1)) || ((cal.get(1) == now.get(1)) && (cal.get(6) > now.get(6)))) {
            return true;
        }
        return false;
    }

    public static boolean isAfterEqualToday(Date date) {
        if (date == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        Calendar now = Calendar.getInstance();
        if ((cal.get(1) > now.get(1)) || ((cal.get(1) == now.get(1)) && (cal.get(6) >= now.get(6)))) {
            return true;
        }
        return false;
    }

    public static boolean isBeforeToday(Date date) {
        if (date == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        Calendar now = Calendar.getInstance();
        if ((cal.get(1) < now.get(1)) || ((cal.get(1) == now.get(1)) && (cal.get(6) < now.get(6)))) {
            return true;
        }
        return false;
    }

    public static boolean isBeforeEqualToday(Date date) {
        if (date == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        Calendar now = Calendar.getInstance();
        if ((cal.get(1) < now.get(1)) || ((cal.get(1) == now.get(1)) && (cal.get(6) <= now.get(6)))) {
            return true;
        }
        return false;
    }

    public static int getDaysBetweenDate(Date headDate, Date tailDate) {
        long gapDays = 0L;
        try {
            gapDays = getDatetimeIntGap(headDate, tailDate, 5);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Integer.valueOf(String.valueOf(gapDays)).intValue();
    }

    public static long getHoursBetweenDate(Date headDate, Date tailDate) {
        long gapHours = 0L;
        try {
            gapHours = getDatetimeIntGap(headDate, tailDate, 10);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return gapHours;
    }

    public static long getHoursBetweenDate2(Date startDt, Date endDt) {
        long totalSeconds = (endDt.getTime() - startDt.getTime()) / 1000L;
        long hours = totalSeconds % 86400L / 3600L;
        long minutes = totalSeconds % 3600L / 60L;
        if (minutes > 0L) {
            hours += 1L;
        }
        return hours;
    }

    public static String getHourMinuteStrBetweenDate(Date startDt, Date endDt) {
        long totalSeconds = (endDt.getTime() - startDt.getTime()) / 1000L;
        long hours = totalSeconds % 86400L / 3600L;
        long minutes = totalSeconds % 3600L / 60L;
        return String.format("%d小时%d分", new Object[]{Long.valueOf(hours), Long.valueOf(minutes)});
    }

    public static long getDatetimeIntGap(Date headDate, Date tailDate, int datepart)
            throws Exception {
        long millisecond = tailDate.getTime() - headDate.getTime();
        long value = 0L;
        switch (datepart) {
            case 14:
                value = millisecond;
                break;
            case 13:
                value = millisecond / 1000L;
                break;
            case 12:
                value = millisecond / 1000L / 60L;
                break;
            case 10:
                value = millisecond / 1000L / 60L / 60L;
                break;
            case 5:
                value = millisecond / 1000L / 60L / 60L / 24L;
                break;
            case 3:
                value = millisecond / 1000L / 60L / 60L / 24L / 7L;
                break;
            case 2:
                Calendar headCal = Calendar.getInstance();
                Calendar tailCal = Calendar.getInstance();
                headCal.setTime(headDate);
                tailCal.setTime(tailDate);
                value = (tailCal.get(1) - headCal.get(1)) * 12 + (tailCal.get(2) - headCal.get(2));

                break;
            case 1:
                headCal = Calendar.getInstance();
                tailCal = Calendar.getInstance();
                headCal.setTime(headDate);
                tailCal.setTime(tailDate);
                value = tailCal.get(1) - headCal.get(1);
                break;
            case 4:
            case 6:
            case 7:
            case 8:
            case 9:
            case 11:
            default:
                throw new Exception();
        }
        return value;
    }

    public static String getDurationDate(Date start, Date end) {
        if ((start == null) || (end == null) || (compare(start, end) < 0L)) {
            return null;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        startCalendar.set(11, 0);
        startCalendar.set(12, 0);
        startCalendar.set(13, 0);
        startCalendar.set(14, 0);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        endCalendar.set(11, 0);
        endCalendar.set(12, 0);
        endCalendar.set(13, 0);
        endCalendar.set(14, 0);

        int durationYear = 0;
        int durationMonth = 0;
        int durationDay = 0;


        startCalendar.add(1, 1);
        while ((startCalendar.before(endCalendar)) || (sameDay(startCalendar, endCalendar))) {
            durationYear++;
            startCalendar.add(1, 1);
        }
        startCalendar.add(1, -1);


        startCalendar.add(2, 1);
        while ((startCalendar.before(endCalendar)) || (sameDay(startCalendar, endCalendar))) {
            durationMonth++;
            startCalendar.add(2, 1);
        }
        startCalendar.add(2, -1);


        startCalendar.add(6, 1);
        durationDay++;
        while ((startCalendar.before(endCalendar)) || (sameDay(startCalendar, endCalendar))) {
            durationDay++;
            startCalendar.add(6, 1);
        }
        StringBuffer duration = new StringBuffer();
        duration.append("" + durationYear);
        duration.append("" + durationMonth);
        duration.append("" + durationDay);
        return duration.toString();
    }

    public static long compare(Date headDate, Date tailDate) {
        return tailDate.getTime() - headDate.getTime();
    }

    private static boolean sameDay(Calendar startCalendar, Calendar endCalendar) {
        if ((startCalendar.get(1) == endCalendar.get(1)) && (startCalendar.get(2) == endCalendar.get(2)) && (startCalendar.get(5) == endCalendar.get(5))) {
            return true;
        }
        return false;
    }

    public static String prettyDateSince(Date date) {
        String sinceMessage = null;
        try {
            HashMap<String, Long> diffDates = diffDates(date, new Date());
            if (0L < ((Long) diffDates.get("diffYears")).longValue()) {
                sinceMessage = "1年前";
            } else if (1L < ((Long) diffDates.get("diffMonths")).longValue()) {
                sinceMessage = String.format("%d 月前", new Object[]{diffDates.get("diffMonths"), Boolean.valueOf(false)});
            } else if (1L == ((Long) diffDates.get("diffMonths")).longValue()) {
                sinceMessage = "上月";
            } else if (13L < ((Long) diffDates.get("diffDays")).longValue()) {
                sinceMessage = String.format("%d 周前", new Object[]{Integer.valueOf(new Double(Math.floor(((Long) diffDates.get("diffDays")).longValue() / 7L)).intValue())});
            } else if (6L < ((Long) diffDates.get("diffDays")).longValue()) {
                sinceMessage = "上周";
            } else if (1L < ((Long) diffDates.get("diffDays")).longValue()) {
                sinceMessage = String.format("%d 天前", new Object[]{diffDates.get("diffDays")});
            } else if (23L < ((Long) diffDates.get("diffHours")).longValue()) {
                sinceMessage = "昨天";
            } else if (1L < ((Long) diffDates.get("diffHours")).longValue()) {
                sinceMessage = String.format("%d 小时前", new Object[]{diffDates.get("diffHours")});
            } else if (1L == ((Long) diffDates.get("diffHours")).longValue()) {
                sinceMessage = "1小时前";
            } else if (((Long) diffDates.get("diffMinutes")).longValue() > 1L) {
                sinceMessage = String.format("%d 分钟前", new Object[]{diffDates.get("diffMinutes")});
            } else {
                sinceMessage = "几秒前";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sinceMessage;
    }

    public static String prettyFurtureDate(Date date) {
        String sinceMessage = null;

        HashMap<String, Long> diffDates = diffDates(new Date(), date);
        if (0L < ((Long) diffDates.get("diffYears")).longValue()) {
            sinceMessage = "1年后";
        } else if (1L < ((Long) diffDates.get("diffMonths")).longValue()) {
            sinceMessage = String.format("%d 月后", new Object[]{diffDates.get("diffMonths"), Boolean.valueOf(false)});
        } else if (1L == ((Long) diffDates.get("diffMonths")).longValue()) {
            sinceMessage = "下月";
        } else if (13L < ((Long) diffDates.get("diffDays")).longValue()) {
            sinceMessage = String.format("%d 周后", new Object[]{Integer.valueOf(new Double(Math.floor(((Long) diffDates.get("diffDays")).longValue() / 7L)).intValue())});
        } else if (6L < ((Long) diffDates.get("diffDays")).longValue()) {
            sinceMessage = "下周";
        } else if (1L < ((Long) diffDates.get("diffDays")).longValue()) {
            sinceMessage = String.format("%d 天后", new Object[]{diffDates.get("diffDays")});
        } else if (23L < ((Long) diffDates.get("diffHours")).longValue()) {
            sinceMessage = "明天";
        } else if (1L < ((Long) diffDates.get("diffHours")).longValue()) {
            sinceMessage = String.format("%d 小时后", new Object[]{diffDates.get("diffHours")});
        } else if (1L == ((Long) diffDates.get("diffHours")).longValue()) {
            sinceMessage = "1小时后";
        } else if (((Long) diffDates.get("diffMinutes")).longValue() > 1L) {
            sinceMessage = String.format("%d 分钟后", new Object[]{diffDates.get("diffMinutes")});
        }
        return sinceMessage;
    }

    private static HashMap<String, Long> diffDates(Date from, Date to) {
        HashMap<String, Long> result = new HashMap(8);
        try {
            Calendar toCal = new GregorianCalendar();
            toCal.setTime(to);
            Calendar fromCal = new GregorianCalendar();
            fromCal.setTime(from);
            long diffYears = 0L;
            long diffMonths = -1L;
            int fromMonth = fromCal.get(2);
            while (fromCal.before(toCal)) {
                fromCal.add(2, 1);
                diffMonths += 1L;
                int currentMonth = fromCal.get(2);
                if (currentMonth == fromMonth) {
                    diffYears += 1L;
                }
            }
            result.put("diffYears", Long.valueOf(diffYears));
            result.put("diffMonths", Long.valueOf(diffMonths));

            long milliSecondDiff = to.getTime() - from.getTime();
            long diffDays = milliSecondDiff / 86400000L;
            long diffHours = milliSecondDiff / 3600000L;
            long timeLeft = milliSecondDiff % 3600000L;
            long diffMinutes = timeLeft / 60000L;

            result.put("diffDays", Long.valueOf(diffDays));
            result.put("diffHours", Long.valueOf(diffHours));
            result.put("diffMinutes", Long.valueOf(diffMinutes));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getCurrentDate());
        System.out.println(getMMDD(new Date()));
        System.out.println(getMMDDHHMM(new Date()));
        System.out.println(getYYYYMMDD(new Date()));
        System.out.println(getYYYYMMDDHHMM(new Date()));
        System.out.println(getHHMM(new Date()));

        System.out.println(toDateTime("2015-04-14 12:50"));
        System.out.println(toDate("2015-04-14"));
        System.out.println(toTime("12:50"));

        System.out.println(getWorkingDayCntByMonth(2015, 4));

        System.out.println(getYYYYMMDD(getNextMonday(Calendar.getInstance(), 1).getTime()));
        System.out.println(getYYYYMMDD(getNextFriday(Calendar.getInstance(), 1).getTime()));


        System.out.println(getWeekNumber(new Date()));
        System.out.println(getYYYYMMDD(getOffsetDate(new Date(), 1)));
        System.out.println(getYYYYMMDD(getOffsetDateForMonth(new Date(), 1)));

        System.out.println(isAfterToday(getOffsetDate(new Date(), -1)));
        System.out.println(isAfterToday(getOffsetDate(new Date(), 1)));
        System.out.println(isAfterToday(getOffsetDate(new Date(), 0)));

        System.out.println(isAfterEqualToday(getOffsetDate(new Date(), -1)));
        System.out.println(isAfterEqualToday(getOffsetDate(new Date(), 1)));
        System.out.println(isAfterEqualToday(getOffsetDate(new Date(), 0)));

        System.out.println(isBeforeToday(getOffsetDate(new Date(), -1)));
        System.out.println(isBeforeToday(getOffsetDate(new Date(), 1)));
        System.out.println(isBeforeToday(getOffsetDate(new Date(), 0)));

        System.out.println(isBeforeEqualToday(getOffsetDate(new Date(), -1)));
        System.out.println(isBeforeEqualToday(getOffsetDate(new Date(), 1)));
        System.out.println(isBeforeEqualToday(getOffsetDate(new Date(), 0)));

        System.out.println(getDaysBetweenDate(getOffsetDate(new Date(), 0), getOffsetDate(new Date(), 3)));
        System.out.println(getHoursBetweenDate(toDateTime("2015-04-12 04:13"), toDateTime("2015-04-12 05:23")));

        System.out.println(getHoursBetweenDate2(toDateTime("2015-04-12 04:13"), toDateTime("2015-04-12 05:23")));


        System.out.println(getDurationDate(getOffsetDate(new Date(), 0), getOffsetDate(new Date(), 3)));

        Date lastYear = parse2DateTime("2015-04-30 14:04:27", "yyyy-MM-dd");
        String resultLastYear = prettyDateSince(lastYear);
        System.out.println("resultLastYear = " + resultLastYear);

        Date fewMonthAgo = parse2DateTime("2015-04-30 14:04:27", "yyyy-MM-dd");
        String resultFewMonthAgo = prettyDateSince(fewMonthAgo);
        System.out.println("resultFewMonthAgo = " + resultFewMonthAgo);

        Date lastMonth = parse2DateTime("2015-04-30 14:04:27", "yyyy-MM-dd");
        String resultLastMonth = prettyDateSince(lastMonth);
        System.out.println("resultLastMonthAgo = " + resultLastMonth);


        Date futureMonth = parse2DateTime("2015-04-30 14:04:27", "yyyy-MM-dd");
        String result = prettyDateSince(futureMonth);
        System.out.println("result = " + result);

        Date futureDays = parse2DateTime("2015-04-30 14:04:27", "yyyy-MM-dd");
        String result2 = prettyDateSince(futureDays);
        System.out.println("result2 = " + result2);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cl = Calendar.getInstance();
        try {
            cl.setTime(sdf.parse("2012-12-11"));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int week = cl.get(3);
        System.out.println(week);
    }
}



/* Location:           D:\repository\cc\hwtech\core\2.0.1-school-SNAPSHOT\core-2.0.1-school-SNAPSHOT.jar

 * Qualified Name:     DateHelper

 * JD-Core Version:    0.7.0.1

 */
